/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.icee.myth.manager.channelHandler;

import com.icee.myth.manager.Manager;
import com.icee.myth.utils.Consts;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import java.io.File;
import java.io.FileInputStream;
import org.apache.commons.io.FileUtils;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.ssl.SslHandler;

/**
 *
 * @author liuxianke
 */
public class BootstrapToManagerHandler extends SimpleChannelUpstreamHandler {

    @Override
    public void channelConnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {

        // Get the SslHandler in the current pipeline.
        // We added it in SecureChatPipelineFactory.
        final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);

        // Get notified when SSL handshake is done.
        ChannelFuture handshakeFuture = sslHandler.handshake();
        handshakeFuture.addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) throws Exception {
                ChannelFuture writeFuture = null;

                if (future.isSuccess()) {
                    if (Manager.INSTANCE.mode == Consts.START_MODE_REMOTE) {
                        writeFuture = future.getChannel().write(Manager.INSTANCE.sourceData);
                    } else {
                        // Once session is secured, send JAR file
                        File jarFile = new File(Manager.INSTANCE.serverJarFileName);
                        int remainLen = (int)FileUtils.sizeOf(jarFile);
                        FileInputStream fis = FileUtils.openInputStream(jarFile);
                        while (remainLen > 0) {
                            int bufLen = (remainLen > 1024)?1024:remainLen;
                            byte[] buf = new byte[bufLen];
                            int readedLen = 0;
                            while (readedLen < bufLen) {
                                readedLen += fis.read(buf, readedLen, bufLen-readedLen);
                            }
                            writeFuture = future.getChannel().write(buf);
                            remainLen -= bufLen;
                        }

                        fis.close();
                    }
                }

                if (writeFuture != null) {
                    writeFuture.addListener(new ChannelFutureListener() {
                        public void operationComplete(ChannelFuture future) throws Exception {
                            future.getChannel().close();
                        }
                    });
                } else {
                    future.getChannel().close();
                }
            }
        });
    }

    @Override
    public void channelDisconnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        MLogger.getlogger().log(LogConsts.LOGTYPE_DEBUG, "Bootstrap channel disconnected.");
    }

    @Override
    public void messageReceived(
            ChannelHandlerContext ctx, MessageEvent e) {
        MLogger.getlogger().log(LogConsts.LOGTYPE_DEBUG, "Manager receive something from bootstrap.");
    }

    @Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getChannel().close();
    }

}
